// Copyright 2009 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <windows.h>
#include <winver.h>

#include <QtCore/QString>

#include "config/binversion.h"
#include "util/common.h"


namespace popdiag {

namespace {

std::wstring QStringToWString(const QString &in) {
  std::wstring rval;
  for (int i = 0; i < in.length(); i++) {
    rval.push_back(static_cast<wchar_t>(in[i].unicode()));
  }
  return rval;
}

QString VersionToString(DWORD major, DWORD minor) {
  return QString("%1.%2.%3.%4").arg(major >> 16).arg(major & 0x0000ffff)
      .arg(minor >> 16).arg(minor & 0x0000ffff);
}

}  // anonymous namespace

bool BinVersion::Read(const QString &binary_path, QString *out) {
  std::wstring binary_path_w(QStringToWString(binary_path));
  DWORD junk = 0;
  DWORD required_size = ::GetFileVersionInfoSize(binary_path_w.c_str(), &junk);
  if (required_size == 0) {
    *out = "Cannot read version info from binary";
    return false;
  }
  scoped_ptr<wchar_t> buffer(new wchar_t[ required_size / sizeof(wchar_t) ]);
  BOOL succeeded = ::GetFileVersionInfo(binary_path_w.c_str(), NULL,
      required_size, buffer.get());
  if (!succeeded) {
    *out = "Cannot read version info from binary";
    return false;
  }

  void *info;
  UINT len;
  if (!VerQueryValue(buffer.get(), L"\\", &info, &len)) {
    *out = "Binary does not contain a version resource block";
    return false;
  }

  VS_FIXEDFILEINFO *ffi
      = reinterpret_cast<VS_FIXEDFILEINFO *>(info);
  *out = VersionToString(ffi->dwFileVersionMS, ffi->dwFileVersionLS);
  return true;
}

} // namespace popdiag
